#ifndef AssetDatabase_h
#define AssetDatabase_h

#include <map>
#include <string>
#include "render_v1_typedef.h"
#include "Engine.h"
#include "ReferenceCounted.h"

namespace hxe
{
    class AssetDatabase : public virtual ReferenceCounted
    {
        friend class Engine;
    public:
       template <typename T>
       T* loadAssetAtPath(std::string path);

       template <typename T>
       T* loadAssetAtPath(std::string path1, std::string path2);

       template <typename T>
       T* loadAssetAtPath(std::vector<std::string> pathes);

    private:
        AssetDatabase() {}
        ~AssetDatabase() 
        {
            std::map<std::string, ReferenceCounted*>::iterator it;
            for (it = assets.begin(); it != assets.end(); it++)
            {
                it->second->drop();
            }
        }

        template <typename T>
        T* getAsset(std::string path);

    private:
        std::map<std::string, ReferenceCounted*> assets;
    };

    template <typename T>
    T* hxe::AssetDatabase::getAsset(std::string path)
    {
        T* asset = (T*)assets[path];

        assert(asset);

        asset->grab();

        return asset;
    }

    template <typename T>
    T* hxe::AssetDatabase::loadAssetAtPath(std::vector<std::string> paths)
    {
        std::string path;
        for (unsigned int i = 0; i < paths.size(); i++)
        {
            path += paths[i];
        }

        if (assets[path] == nullptr)
        {
            T* asset = new T(paths);
            assets[path] = asset;
        }

        return getAsset<T>(path);
    }

    template <typename T>
    T* hxe::AssetDatabase::loadAssetAtPath(std::string path1, std::string path2)
    {
        std::string path = path1 + path2;
        if (assets[path] == nullptr)
        {
            T* asset = new T(path1, path2);
            assets[path] = asset;
        }

        return getAsset<T>(path);
    }

    template <typename T>
    T* hxe::AssetDatabase::loadAssetAtPath(std::string path)
    {
        if (assets[path] == nullptr)
        {
            T* asset = new T(path);
            assets[path] = asset;
        }

        return getAsset<T>(path);
    }
}

#endif // AssetDatabase_h
